package com.siqi.hr.system.common.controller;

import com.siqi.hr.common.Constants;
import com.siqi.hr.common.entity.ExportEntity;
import com.siqi.hr.common.utils.*;
import com.siqi.hr.common.utils.json.JSONArray;
import com.siqi.hr.system.common.authority.DataScope;
import com.siqi.hr.system.common.chan.ConditionChan;
import com.siqi.hr.system.common.chan.TableChan;
import com.siqi.hr.system.common.enums.FieldPosition;
import com.siqi.hr.system.common.service.CommonOperationService;
import com.siqi.hr.system.common.service.ExportImportService;
import com.siqi.hr.system.common.sql.Condition;
import com.siqi.hr.system.common.sql.SField;
import com.siqi.hr.system.common.sql.STable;
import com.siqi.hr.system.custom.entity.EntityRecord;
import com.siqi.hr.system.custom.entity.FieldRecord;
import com.siqi.hr.system.custom.service.EntityRecordService;
import com.siqi.hr.system.organization.entity.Dept;
import com.siqi.hr.system.organization.entity.Employee;
import com.siqi.hr.system.organization.entity.RoleEntityScope;
import com.siqi.hr.system.organization.service.RoleService;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * 导入导出通用控制器
 * @author     xiaogq
 * @date       2017-01-05
 */
@Controller
@RequestMapping("ExportImport")
public class ExportImportController {

    @Autowired
    private CommonOperationService commonOperationService;

    @Autowired
    private EntityRecordService entityRecordService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ExportImportService exportImportService;

    /**
     * 初始化导出页面
     * @author     xiaogq
     */
    @RequestMapping("initExportEntity")
    public ModelAndView initExportEntity(HttpServletRequest request, HttpSession session){
        Employee employee = (Employee) session.getAttribute("emp");
        //得到实体id
        Integer entityId = ServletRequestUtils.getIntParameter(request, "entityId", 0);
        FieldPosition position = FieldPosition.List;
        // 获得实体导出字段
        List<FieldRecord> allFieldList = commonOperationService.queryAllEntityLayoutField(entityId,position);
        //如果是后台布局管理中设计视图布局、过滤条件
        List<FieldRecord> showFieldList = commonOperationService.querySysSetEntityLayoutField(entityId, position);
        // 获得影藏字段
        List<FieldRecord> hideFieldList = new ArrayList<FieldRecord>();
        for (FieldRecord field : allFieldList) {
            if(!showFieldList.contains(field)){
                hideFieldList.add(field);
            }
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("entityId", entityId);
        mav.addObject("leftlist", hideFieldList);
        mav.addObject("rightlist", showFieldList);
        mav.setViewName("common/export/entity_export");
        return mav;
    }

    /**
     * 导出实体数据通用方法
     * @author     xiaogq
     */
    @RequestMapping("entityExport")
    @ResponseBody
    public Map<String, Object> entityExport(HttpServletRequest request,ExportEntity exportEntity) {
        Map modelMap = new HashMap();
        //得到实体id
        int tableCode = exportEntity.getEntityId();
        //根据实体id查询实体记录信息
        EntityRecord entity = entityRecordService.queryEntityRecordById(tableCode);
        Employee emp = (Employee)request.getSession().getAttribute("emp");
        Dept dept = (Dept)request.getSession().getAttribute("dept");
        if(tableCode == TableConstant.EMPLOYEE_TCODE){//如果是导出员工实体则不导出管理员数据
            exportEntity.setSearchIds(Constants.ROOTEMPID);
        }
        exportEntity.setDept(dept);
        exportEntity.setEmployee(emp);
        exportEntity.setTablecode(tableCode);
        //导出excel文件存放路径
        String url = request.getServletContext().getRealPath("") + Constants.EXPORT_FILE_PATH;
        exportEntity.setUrl(url);
        //设置主表信息
        STable sTable = new STable(STable.TABLE_HEAD+tableCode);
        TableChan tableChan = new TableChan(sTable);
        exportEntity.setTableChan(tableChan);
        ConditionChan cc = new ConditionChan();
        // 指定查询的数据ID
        String searchIds = StringUtil.getString(exportEntity.getSearchIds());
        if( StringUtils.isNotEmpty(searchIds) ){
            cc.add(new Condition(new SField("id",new STable(STable.TABLE_HEAD+tableCode)), Condition.ConditionType.notin , searchIds));
        }
        // 添加是否有效数据验证条件
        Condition validCondition = listValidDataCondition(exportEntity,entity);
        if(null != validCondition){
            cc.add(validCondition);
        }
        // 数据权限（肖功钦）
        RoleEntityScope scope = new RoleEntityScope(DataScope.NONE.name());
        //如果实体不是受权限控制的实体
        if( !entity.getPermission()){
            scope = new RoleEntityScope(DataScope.ALL.name());
        }else{//如果实体是受权限控制的实体(肖功钦)
            scope = roleService.queryRoleDataScope(emp.getRole().getId(), entity);
        }
        exportEntity.setScope(scope);
        // 其他过滤条件
        Set<Condition> conditios = exportEntity.getMutilSearch();
        //普通查询处理
        for(Condition condition : conditios){
            cc.add(condition);	//加入条件族
        }
        exportEntity.setConditionChan(cc);
        exportEntity.setBootstrapQuery(true);
        exportEntity.setSearchVal("");
        //排序字段
        exportEntity.setOrderby(STable.TABLE_HEAD+tableCode + ".id " + " desc ");
        //查询需要导出的数据
        Map<String, String> map = exportImportService.entityExport(exportEntity, emp);
        modelMap.put("success", "true");
        modelMap.put("path", map.get("path"));
        modelMap.put("name", map.get("name"));
        return modelMap;
    }

    /**
     * 根据实体是否是回收站实体给列表添加“查询有效数据”条件
     *@author     xiagq 2016 08 24
     *@param      exportEntity             搜索条件对象
     *@return     entityRecord             实体对象信息
     */
    public Condition listValidDataCondition(ExportEntity exportEntity,EntityRecord entityRecord){
        Integer entityId = exportEntity.getEntityId();
        Set<Condition> conditios = exportEntity.getMutilSearch();
        //判断过滤条件里是否包含是否有效数据的验证
        Condition validCond = null;
        Boolean contain = false;
        for(Condition con : conditios){
            if (con.getField().getName().equals("valid_data_bit")) {
                contain = true;
                validCond = con;
                break;
            }
        }
        //如果没有是否有效数据的验证，则判断是否使用回收站实体，是使用回收站实体默认添加是否有效数据的验证
        if(!contain){
            if(entityRecord.getUseRecyclebin()){
                return new Condition(new SField("valid_data_bit", new STable(STable.TABLE_HEAD+entityId)), Condition.ConditionType.eq,exportEntity.isValidFlag()+"");
            }
        }
        return validCond;
    }

    /**
     * 初始化导入文件选择页面
     *@author     xiagq 2017-01-06
     *@param      entityId             实体id
     *@return     entityRecord             实体对象信息
     */
    @RequestMapping("importchoosefile")
    public ModelAndView importChooseFile(HttpServletRequest request,int entityId){
        ModelAndView view = new ModelAndView();
        String entityName = ServletRequestUtils.getStringParameter(request,"entityName","");
        view.addObject("entityId", entityId);
        view.addObject("entityName", entityName);
        view.setViewName("common/export/import_choose_file");
        return view;
    }

    /**
     * 通用导入读取excel数据方法
     * @author               xiaogq
     * @param entityId       实体id
     * @throws Exception
     */
    @RequestMapping(value="initshowImportFile", method= RequestMethod.POST)
    @ResponseBody
    public String initshowImportFile(HttpServletRequest request,int entityId){
        JSONObject backJson = new JSONObject();
        try {
            //获取实体名称
            String entityName = request.getParameter("entityName");
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
            MultipartFile file = multipartHttpServletRequest.getFile("file");
            //获取文件名称
            String fileName = file.getOriginalFilename();
            //获取文件导出时的存放目录
            String ctxPath = request.getServletContext().getRealPath("") + Constants.EXPORT_FILE_PATH;
            String servicerurl = ctxPath + fileName;
            //先删除指定文件
            FileUtils.deletefile(ctxPath, fileName);
            //复制目录到指定路径
            FileUtils.copy(file.getBytes(),servicerurl);
            //得到文件后缀类型
            String fileType = fileName.substring(fileName.indexOf("."));
            //存放列头信息
            List<String> importCells = new ArrayList<String>();
            //存放文件中的数据集合
            List<Map<String,Object>> listMap = new ArrayList<Map<String,Object>>();
            if (fileType.equals(".csv")){//如果是导入csv类型文件数据
                //得到分割符
                String splitValue = ServletRequestUtils.getStringParameter(request,"punctuate",",");
                //得到编码格式
                String importEcord = ServletRequestUtils.getStringParameter(request,"importEcord","UTF-8");
                //读取csv文件数据
                Map<String,Object> readCsvMap = ExportUtils.importCsv(servicerurl, splitValue, importEcord);
                importCells = (List<String>) readCsvMap.get("importCells");
                listMap = (List<Map<String,Object>>)readCsvMap.get("listMap");
            } else {//如果导入excel
                //读取excel文件中的数据
                Map<String,Object> map = ExportUtils.poiReadEntityExcel(servicerurl);
                Map<String,Object> columnMap = (Map<String,Object>)map.get("columnMap");
                importCells = (List<String>)map.get("importCells");
                listMap = (List<Map<String,Object>>)map.get("listMap");
                String sheetName = (String)map.get("sheetName");
                request.getSession().setAttribute("columnMap", columnMap);
                request.getSession().setAttribute("sheetName", sheetName);
            }
            request.getSession().setAttribute("importCells", importCells);
            request.getSession().setAttribute("listMap", listMap);
            backJson.put("hasValue", listMap.size());
            backJson.put("entityName", entityName);
            backJson.put("fileName", fileName);
            backJson.put("entityId", entityId);
            backJson.put("fileType", fileType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return backJson.toString();
    }

    /**
     * 通用导入读取excel数据渲染到表格方法
     * @author               xiaogq
     * @param entityId       实体id
     * @throws Exception
     */
    @RequestMapping("showImportFileTable")
    public ModelAndView showImportFileTable(HttpServletRequest request,int entityId){
        ModelAndView view = new ModelAndView();
        //得到实体中文名称
        String entityName = ServletRequestUtils.getStringParameter(request,"entityName","");
        String fileName = ServletRequestUtils.getStringParameter(request,"fileName","");
        //得到excel sheet页名称
        String sheetName = (String)request.getSession().getAttribute("sheetName");
        //得到表格显示的列头
        Map<String,Object> columnMap = (Map) request.getSession().getAttribute("columnMap");
        view.addObject("entityId", entityId);
        view.addObject("entityName", entityName);
        view.addObject("fileName", fileName);
        view.addObject("sheetMap", sheetName);
        view.addObject("column", columnMap.get("columns") == null ? "" : columnMap.get("columns"));
        view.setViewName("common/export/import_value_show");
        return view;
    }

    /**
     * 通用导入读取excel数据渲染表格数据方法
     * @author               xiaogq
     * @throws Exception
     */
    @RequestMapping("showImportValue")
    @ResponseBody
    public Map<String, Object> showImportValue(HttpServletRequest request){
        Map resultMap = new HashMap();
        List<Map<String,Object>> listMap = (List<Map<String,Object>>) request.getSession().getAttribute("listMap");
        resultMap.put(Const.TOTAL, listMap.size());
        resultMap.put(Const.ROWS, listMap);
        return resultMap;
    }

    /**
     * 通用导入文件实体数据字段映射页面
     * @author           xiaogq
     * @param entityId   实体id
     * @return
     * @throws Exception
     */
    @RequestMapping("resolveImportFileCell")
    public ModelAndView resolveImportFileCell(HttpServletRequest request,int entityId){
        ModelAndView view = new ModelAndView();
        //获取excel Sheet索引
        int sheetIndex = ServletRequestUtils.getIntParameter(request,"sheetIndex",0);
        //得到实体中文名称
        String entityName = ServletRequestUtils.getStringParameter(request,"entityName","");
        //获得文件名称
        String fileName = ServletRequestUtils.getStringParameter(request,"fileName","");
        //获取实体引用字段与非引用字段信息
        Map<String, Object> map = this.commonOperationService.getAllFieldsOfEntityExceptQuote(entityId);
        //获取实体非引用字段信息
        List<FieldRecord> mainFields = (List<FieldRecord>) map.get("mainFields");
        //获取实体引用字段信息
        Map<FieldRecord,List<FieldRecord>> quoteFields = (Map<FieldRecord, List<FieldRecord>>) map.get("map");
        List cellsMap = (List)request.getSession().getAttribute("importCells");
        view.addObject("mainFields", mainFields);
        view.addObject("map", quoteFields);
        view.addObject("list", cellsMap);
        view.addObject("entityId", entityId);
        view.addObject("entityName", entityName);
        view.addObject("fileName", fileName);
        view.setViewName("common/export/import_field_match");
        return view;
    }

    /**
     * 导入实体数据通用方法
     * @author           xiaogq
     * @return
     */
    @RequestMapping("importEntity")
    @ResponseBody
    public Map<String, Object> importEntity(HttpServletRequest request){
        Map modelMap = new HashMap();
        try {
            //获取实体id
            String entityId = ServletRequestUtils.getStringParameter(request,"entityId","0");
            //获取导入实体字段Json数据信息
            String importMainFieldJsonChar = ServletRequestUtils.getStringParameter(request,"importFieldJsonChar","");
            JSONArray imfJsonArray = new JSONArray(importMainFieldJsonChar);
            //获取导入文件中的所有数据
            List<Map<String,Object>> list = (List<Map<String,Object>>) request.getSession().getAttribute("listMap");
            //执行导入数据方法
            Map<String, Object> rebackImportInfo = exportImportService.importEntityData(request,entityId,imfJsonArray,list);
            modelMap.put("boo", rebackImportInfo.get("boo"));
            modelMap.put("allNumber", rebackImportInfo.get("allNumber"));
            modelMap.put("successNumber", rebackImportInfo.get("successNumber"));
            modelMap.put("bool", rebackImportInfo.get("bool"));
            if (((Boolean)rebackImportInfo.get("bool")).booleanValue()) {
                modelMap.put("path", rebackImportInfo.get("path"));
                modelMap.put("name", rebackImportInfo.get("name"));
            }
            modelMap.put("importSuc", true);
        } catch (Exception e) {
            modelMap.put("importSuc", false);
            e.printStackTrace();
        }
        return modelMap;
    }

}
